/******************************************************************************/
/* @ All Rights Reserved Copyright (C) 2014 broada,Ltd.                       */
/*                                                                            */
/*  NAME      = db2_reply_obj.c                                               */
/*  NOTE      = TDS 请求解析                                                  */
/*  DATE      = 2015/03/19 by zhengxd                                         */
/******************************************************************************/
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <stdint.h>

#include "db2_param.h"
#include "db2_reply_obj.h"

/*******************************************************************************
*  FUNC     :  解析EXCSATRD
*  ARGS     :  p_st_private (DB2私有数据)
*           :  i_whole_flg(packet完整标识)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int db2_parse_excsatrd(L7session_db2_private *p_st_private, int i_whole_flg)
{
    int i_ret = APM_L7_ANALYZE_SUCC;
    int i_param_cp = 0;
    unsigned int ui_param_bd_len = 0;
    L7session_db2 *p_st_sess = p_st_private->p_st_sess;
    L7_fragment_db2 *p_st_fragment = p_st_private->p_st_fragment;
    Frbyte_Packet *p_st_data = p_st_fragment->p_st_data;

    /* 解析参数 */
    while (p_st_fragment->ui_left_ddm_len)
    {
        i_ret = db2_get_param_hd_info(p_st_fragment, i_whole_flg
                                     , &p_st_fragment->ui_left_ddm_len
                                     , &i_param_cp, &ui_param_bd_len);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            frdbg("EXCSATRD: Need more data or parse failed!\n");
            return i_ret;
        }

        switch (i_param_cp)
        {
            /* EXTNAM/SRVCLSNM/SRVNAM/SRVRLSLV不取值,直接跳过 */
            case DRDA_CP_EXTNAM:    //External name
            case DRDA_CP_SRVCLSNM:  //server class name
            case DRDA_CP_SRVNAM:    //Server name
            case DRDA_CP_SRVRLSLV:  //server release level
                i_ret = db2_skip_param(p_st_data, ui_param_bd_len, i_whole_flg
                                      , &p_st_fragment->ui_left_ddm_len);
                break;

            /* 在参数Manager-level中取得CSSID */
            case DRDA_CP_MGRLVLLS:  //Manager-level List
                i_ret = db2_parse_mgrlvlls(p_st_data, ui_param_bd_len
                                          , i_whole_flg, p_st_sess->arr_ccsid
                                          , sizeof(p_st_sess->arr_ccsid)
                                          , &p_st_fragment->ui_left_ddm_len);
                break;

            default:
                frdbg("EXCSATRD: Unknow parameter!\n");
                return APM_L7_ANALYZE_FAIL;
        }

        /* 数据不足或者解析出错 */
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            frdbg("EXCSATRD: need more data or parse failed!\n");
            return i_ret;
        }
        /* 为取下一个参数做初始化准备 */
        p_st_fragment->i_param_cp = DRDA_CP_NULL;
    }

    p_st_fragment->i_req_resp_cp = DRDA_CP_NULL;
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析ACCSECRD
*  ARGS     :  p_st_private (DB2私有数据)
*           :  i_whole_flg(packet完整标识)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int db2_parse_accsecrd(L7session_db2_private *p_st_private, int i_whole_flg)
{
    int i_ret = APM_L7_ANALYZE_SUCC;
    int i_param_cp = 0;
    unsigned int ui_param_bd_len = 0;
    L7_fragment_db2 *p_st_fragment = p_st_private->p_st_fragment;
    Frbyte_Packet *p_st_data = p_st_fragment->p_st_data;

    /* 解析参数 */
    while (p_st_fragment->ui_left_ddm_len)
    {
        i_ret = db2_get_param_hd_info(p_st_fragment, i_whole_flg
                                     , &p_st_fragment->ui_left_ddm_len
                                     , &i_param_cp, &ui_param_bd_len);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            frdbg("ACCSECRD: need more data or get parameter info failed!\n");
            return i_ret;
        }

        switch (i_param_cp)
        {
            /* 所有parameter都不取值,直接跳过 */
            case DRDA_CP_ENCALG:    //Encryption Algorithm
            case DRDA_CP_ENCKEYLEN: //Encryption Key Length
            case DRDA_CP_PLGINLST:  //Security Plug-in List
            case DRDA_CP_SECCHKCD:  //Security Check Code
            case DRDA_CP_SECMEC:    //Security Check Code
            case DRDA_CP_SECTKN:    //Security Token
                i_ret = db2_skip_param(p_st_data, ui_param_bd_len, i_whole_flg
                                      , &p_st_fragment->ui_left_ddm_len);
                break;

            default:
                frdbg("ACCSECRD: Unknow parameter!\n");
                return APM_L7_ANALYZE_FAIL;
        }

        /* 数据不足或者解析出错 */
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            frdbg("ACCSECRD: need more data or parse failed!\n");
            return i_ret;
        }
        /* 为取下一个参数做初始化准备 */
        p_st_fragment->i_param_cp = DRDA_CP_NULL;
    }

    p_st_fragment->i_req_resp_cp = DRDA_CP_NULL;
    return APM_L7_ANALYZE_SUCC;
}

/*******************************************************************************
*  FUNC     :  解析ENDQRYRM
*  ARGS     :  p_st_private (DB2私有数据)
*           :  i_whole_flg(packet完整标识)
*  RTN      :  APM_L7_ANALYZE_SUCC  (success)
*              APM_L7_ANALYZE_TODO  (more data)
*              APM_L7_ANALYZE_FAIL  (failed)
*  NOTE     :
*******************************************************************************/
int db2_parse_endqryrm(L7session_db2_private *p_st_private, int i_whole_flg)
{
    int i_ret = APM_L7_ANALYZE_SUCC;
    int i_param_cp = 0;
    unsigned int ui_param_bd_len = 0;
    L7_resp_db2 *p_st_resp = p_st_private->p_st_resp;
    L7session_db2 *p_st_sess = p_st_private->p_st_sess;
    L7_fragment_db2 *p_st_fragment = p_st_private->p_st_fragment;
    Frbyte_Packet *p_st_data = p_st_fragment->p_st_data;

    /* 解析参数 */
    while (p_st_fragment->ui_left_ddm_len)
    {
        i_ret = db2_get_param_hd_info(p_st_fragment, i_whole_flg
                                     , &p_st_fragment->ui_left_ddm_len
                                     , &i_param_cp, &ui_param_bd_len);
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            frdbg("ENDQRYRM: need more data or parse failed!\n");
            return i_ret;
        }

        switch (i_param_cp)
        {
            case DRDA_CP_SVRCOD:
                /* 根据协议SVRCOD parameter的长度是6, 即body长度是2 */
                if (ui_param_bd_len != 2)
                {
                    frdbg("ENDQRYRM: parameter length is incorrect!\n");
                    return APM_L7_ANALYZE_FAIL;
                }
                i_ret = db2_get_bindr(p_st_data, 2, i_whole_flg, &p_st_resp->i64_svrcod
                                     , &p_st_fragment->ui_left_ddm_len);
                break;

            case DRDA_CP_RDBNAM:
                /* RDBNAM不取值 */
                i_ret = db2_skip_param(p_st_data, ui_param_bd_len, i_whole_flg
                                      , &p_st_fragment->ui_left_ddm_len);
                break;

            case DRDA_CP_SRVDGN:
                /* 取得服务器诊断信息*/
                /* RDBNFNRM中有两个SRVDGN参数, 实际情况不会发生 */
                if (p_st_resp->p_error_msg)
                {
                    frfree(p_st_resp->p_error_msg);
                    p_st_resp->p_error_msg = NULL;
                }
                /* 注意: SRVDGN字段协议定义成BYTSTRDR, 实际上DB2将其当做NAMDR */
                i_ret = db2_get_chrstrdr(p_st_data, ui_param_bd_len, i_whole_flg
                                        , p_st_sess->arr_ccsid
                                        , &p_st_resp->p_error_msg
                                        , &p_st_fragment->ui_left_ddm_len);
                break;

            default:
                frdbg("ENDQRYRM: Unknow parameter!\n");
                return APM_L7_ANALYZE_FAIL;
        }

        /* 判断取值正误 */
        if (i_ret != APM_L7_ANALYZE_SUCC)
        {
            frdbg("ENDQRYRM: need more data or parse failed!\n");
            return i_ret;
        }
        /* 为取下一个参数做初始化准备 */
        p_st_fragment->i_param_cp = DRDA_CP_NULL;
    }

    /* 根据协议可知svrcod是8时sqlstate从SQLCARD取 */
    p_st_fragment->i_req_resp_cp = DRDA_CP_NULL;
    return APM_L7_ANALYZE_SUCC;
}

